home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Floppyshop 2
/
Floppyshop - 2.zip
/
Floppyshop - 2.iso
/
art&graf.ix
/
art-4542
/
rshade30
/
gray22.s
< prev
next >
Wrap
Text File
|
1993-09-06
|
17KB
|
478 lines
;From gatech!wrdis01!mips!spool.mu.edu!cs.umn.edu!msi.umn.edu!noc.MR.NET!ns!ns!logajan Mon May 20 13:45:34 EDT 1991
;Article: 39871 of comp.sys.atari.st
;Path: gatech!wrdis01!mips!spool.mu.edu!cs.umn.edu!msi.umn.edu!noc.MR.NET!ns!ns!logajan
;From: logajan@ns.network.com (John Logajan)
;Newsgroups: comp.sys.atari.st
;Subject: Display 22 levels of gray on color mon.
;Message-ID: <1991May19.210150.7671@ns.network.com>
;Date: 19 May 91 21:01:50 GMT
;Sender: news@ns.network.com
;Organization: Network Systems Corporation
;Lines: 436
;Posted: Sun May 19 16:01:50 1991
;Originator: logajan@ns
;Nntp-Posting-Host: ns
;Sender: kilian
;Status: OR
;
;
; gray22 -- original code by John Logajan 5-19-91, PUBLIC DOMAIN.
; logajan@ns.network.com
;
; This subroutine is called by the ATARI ST COLOR user to go into
; 22 level grayscale display mode (dithered flicker.) Any keys pressed
; from the keyboard will return control back to the user's calling program.
; Keys pressed will not be disturbed and will be available for inspection
; by normal TOS routines. This routine uses 64k just below the normal
; screen RAM area.
;
; This will display a 320x200 minimum window in 22 level grayscale.
; You can have arbitrarily large virtual displays. Scrolling the
; window across the virtual image is accomplished merely by calling this
; program with a new starting (upper left corner) address.
;
; The virtual image must be in the form of one byte per pixel. Legal
; intensity values in each byte range from 0 to 21 (decimal.) The image
; is organized as left to right and top to bottom.
;
; The call to gray22 must include:
;
; A0 set to the window starting point (upper left corner) in the image.
; D0 set to the length of the virtual image horizontal line (bytes).
; D0 should never change unless the virtual image size changes.
; D0 is *not* 320 unless the virtual image size is the same as the
; window size (the window size *is* always 320.)
;
; There are three subroutines below. One initializes everything, one
; restores everything on exit, one displays the window and also has
; an entry point for simply going back into display mode without
; changing the current screen contents (useful for quick returns
; from invalid keypressed keys.)
;
; jsr grayinit -- should be called once to go into low resolution mode.
; Calling grayinit twice or more without intervening
; calls to grayexit will cause original modes to be
; forgotten.
;
; jsr grayexit -- should be called once on exit to restore previous modes.
; Don't call grayexit if you haven't yet called grayinit.
;
; jsr gray22 -- should be called with A0 and D0 set, to update display.
; Don't call gray22 if you haven't yet called grayinit.
;
; jsr grayshow -- should be called to bypass update and continue previous
; display. gray22 automatically executes grayshow.
; Don't call grayshow if you haven't yet called grayinit
; and gray22 at least once.
text
even
globl grayinit, grayexit, gray22, grayshow
;
; Here is gray22, be sure to have called grayinit before calling this.
; Also be sure to set A0 and D0 before each gray22 call.
;
gray22: movem.l d3-d7/a2-a6,regsave
move.l a0,corner ; save the starting corner
sub.l #320,d0 ; compute and save the window factor
move.l d0,wrapit
;
; We get 22 shades of gray by flipping between three screens each
; with different combinations of eight shades of gray (the atari
; hardware limit.) The table below shows the general theory:
;
; Screen Screen Screen
; 0 1 2 Shade 0 1 2 Shade 0 1 2 Shade
;
; 7 7 7 21 4 4 5 13 2 2 1 5
; 7 7 6 20 4 4 4 12 1 1 2 4
; 6 6 7 19 4 4 3 11 1 1 1 3
; 6 6 6 18 3 3 4 10 1 1 0 2
; 6 6 5 17 3 3 3 9 0 0 1 1
; 5 5 6 16 3 3 2 8 0 0 0 0
; 5 5 5 15 2 2 3 7
; 5 5 4 14 2 2 2 6
;
; In addition, to keep flicker to a minimum, we phase dither each intensity
; with a three horizontal by three vertical pixel intensity interlace.
; For instance, a block of intensity-18 pixels would be displayed as such:
;
; ... First Screenful ... ... Second Screenful ... ...Third Screenful...
; ... 6 6 7 6 6 7 6 6 ... ... 6 7 6 6 7 6 6 7 ... ... 7 6 6 7 6 6 7 ...
; ... 6 7 6 6 7 6 6 7 ... ... 7 6 6 7 6 6 7 6 ... ... 6 6 7 6 6 7 6 ...
; ... 7 6 6 7 6 6 7 6 ... ... 6 6 7 6 6 7 6 6 ... ... 6 7 6 6 7 6 6 ...
; ... etc ... ... etc ... ... etc ...
;
;
; Do first screen full.
;
move.w #-1,-(sp) ; keep resolution
move.l phy0,-(sp) ; switch to phys addr screen #0
move.l phy0,-(sp) ; switch to logical addr screen #0
move.w #5,-(sp) ; setscreen
trap #14
add.l #12,sp
move.l #gtable,a5 ; conversion table base address
move.l corner,a2 ; get start point
move.l phy0,a1 ; get screen start address
;
; First of three grouped horizontal lines.
;
move.w #66,d7 ; 200 lines
b0r1: move.l #templine,a3 ; where we build a temporary line
move.w #106,d6 ; 320 bits per line
b0r2: clr.l d0
move.b (a2)+,d0
move.b (a5,d0),d0 ; dither pixel horz 0 -- line 0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b 22(a5,d0),d0 ; dither pixel horz 1 -- line 0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b 44(a5,d0),d0 ; dither pixel horz 2 -- line 0
move.b d0,(a3)+
dbf d6,b0r2
add.l wrapit,a2 ; window correction factor
subq.l #1,a2 ; backup 1 pixel
jsr repac320
;
; Second of three grouped horizontal lines
;
move.l #templine,a3
move.w #106,d6
b0r3: clr.l d0
move.b (a2)+,d0
move.b 22(a5,d0),d0 ; dither pixel horz 0 -- line 1
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b 44(a5,d0),d0 ; dither pixel horz 1 -- line 1
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b (a5,d0),d0 ; dither pixel horz 2 -- line 1
move.b d0,(a3)+
dbf d6,b0r3
add.l wrapit,a2 ; window correction factor
subq.l #1,a2 ; backup 1 pixel
jsr repac320
;
; Third of three grouped horizontal lines.
;
move.l #templine,a3
move.w #106,d6
b0r4: clr.l d0
move.b (a2)+,d0
move.b 44(a5,d0),d0 ; dither pixel horz 0 -- line 2
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b (a5,d0),d0 ; dither pixel horz 1 -- line 2
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b 22(a5,d0),d0 ; dither pixel horz 2 -- line 2
move.b d0,(a3)+
dbf d6,b0r4
add.l wrapit,a2 ; window correction factor
subq.l #1,a2 ; backup 1 pixel
jsr repac320 ; paint a screen line
dbf d7,b0r1 ; go do next three screen lines
;
; Do second screen.
;
move.l corner,a2 ; get start point
move.l phy1,a1 ; get screen start address
move.w #66,d7 ; 200 lines
b1r1: move.l #templine,a3 ; where we build a temporary line
move.w #106,d6 ; 320 bits per line
b1r2: clr.l d0
move.b (a2)+,d0
move.b 22(a5,d0),d0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b 44(a5,d0),d0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b (a5,d0),d0
move.b d0,(a3)+
dbf d6,b1r2
add.l wrapit,a2 ; window correction factor
subq.l #1,a2 ; backup 1 pixel
jsr repac320
move.l #templine,a3
move.w #106,d6
b1r3: clr.l d0
move.b (a2)+,d0
move.b 44(a5,d0),d0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b (a5,d0),d0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b 22(a5,d0),d0
move.b d0,(a3)+
dbf d6,b1r3
add.l wrapit,a2 ; window correction factor
subq.l #1,a2 ; backup 1 pixel
jsr repac320
move.l #templine,a3
move.w #106,d6
b1r4: clr.l d0
move.b (a2)+,d0
move.b (a5,d0),d0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b 22(a5,d0),d0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b 44(a5,d0),d0
move.b d0,(a3)+
dbf d6,b1r4
add.l wrapit,a2 ; window correction factor
subq.l #1,a2 ; backup 1 pixel
jsr repac320 ; paint a screen line
dbf d7,b1r1 ; go do next three screen lines
;
; Do third screen
;
move.l corner,a2 ; get start point
move.l phy2,a1 ; get screen start address
move.w #66,d7 ; 200 lines
b2r1: move.l #templine,a3 ; where we build a temporary line
move.w #106,d6 ; 320 bits per line
b2r2: clr.l d0
move.b (a2)+,d0
move.b 44(a5,d0),d0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b (a5,d0),d0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b 22(a5,d0),d0
move.b d0,(a3)+
dbf d6,b2r2
add.l wrapit,a2 ; window correction factor
subq.l #1,a2 ; backup 1 pixel
jsr repac320
move.l #templine,a3
move.w #106,d6
b2r3: clr.l d0
move.b (a2)+,d0
move.b (a5,d0),d0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b 22(a5,d0),d0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b 44(a5,d0),d0
move.b d0,(a3)+
dbf d6,b2r3
add.l wrapit,a2 ; window correction factor
subq.l #1,a2 ; backup 1 pixel
jsr repac320
move.l #templine,a3
move.w #106,d6
b2r4: clr.l d0
move.b (a2)+,d0
move.b 22(a5,d0),d0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b 44(a5,d0),d0
move.b d0,(a3)+
clr.l d0
move.b (a2)+,d0
move.b (a5,d0),d0
move.b d0,(a3)+
dbf d6,b2r4
add.l wrapit,a2 ; window correction factor
subq.l #1,a2 ; backup 1 pixel
jsr repac320 ; paint a screen line
dbf d7,b2r1 ; go do next three screen lines, else show
bra graysh1
;
; This section of the code continuously flips through the three video
; screens to generate the flicker grayscale effect. Any keypress will
; cause a subroutine exit back to the user calling program.
;
; You can call this directly if you want to avoid the delay of updating
; a screen that doesn't need to be updated. However, it makes no sense
; to call this if you haven't already called grayinit and gray22 at least
; once prior.
;
grayshow: movem.l d3-d7/a2-a6,regsave
graysh1: move.w #37,-(sp) ; wait for vsync
trap #14
addq.l #2,sp
move.w #-1,-(sp) ; keep resolution
move.l phy1,-(sp) ; switch phys addr to screen #1
move.l #-1,-(sp) ; keep logical addr
move.w #5,-(sp) ; setscreen
trap #14
add.l #12,sp
move.w #37,-(sp) ; wait for vsync
trap #14
addq.l #2,sp
move.w #-1,-(sp) ; keep res
move.l phy2,-(sp) ; switch phys addr to screen #2
move.l #-1,-(sp) ; keep logical addr
move.w #5,-(sp) ; setscreen
trap #14
add.l #12,sp
move.w #37,-(sp) ; wait for vsync
trap #14
addq.l #2,sp
move.w #-1,-(sp) ; keep res
move.l phy0,-(sp) ; switch phys addr to screen #1
move.l #-1,-(sp) ; keep logical addr
move.w #5,-(sp) ; setscreen
trap #14
add.l #12,sp
move.w #$0b,-(sp) ; check for keypress
trap #1
addq.l #2,sp
tst.w d0
beq grayshow ; keep flipping screens if no keypress
movem.l regsave,d3-d7/a2-a6
rts ; else exit back to calling user program
;
; Subroutine to distribute one line's worth of color register numbers
; into goofy Atari video ram format. (This is five times faster than
; using the Atari Line-A Put-Pixel A001 routine.)
;
repac320: move.w #19,d6 ; do 20 groups of 16 pixels (320)
move.l #templine,a0 ; point to temp line of color registers.
repack16: move.w #15,d5 ; do 16 pixels
repack: move.b (a0)+,d0 ; get each color register number.
roxr.b #1,d0
roxl.w #1,d1 ; pick off lsb
roxr.b #1,d0
roxl.w #1,d2 ; pick off lsb+1
roxr.b #1,d0
roxl.w #1,d3 ; pick off lsb+2
dbf d5,repack
move.w d1,(a1)+ ; 16 pixel LSB's (a1 points to video ram)
move.w d2,(a1)+
move.w d3,(a1)+
clr.w (a1)+ ; 16 pixel MSB's (MSB always zero)
dbf d6,repack16
rts ; return to calling program
;
; This routine allocates an additional 64k bytes for two more screens,
; saves the original palette and resolution for later restore. And
; switches to low resolution and installs the grayscale palette.
;
grayinit: movem.l d3-d7/a2-a6,regsave
move.w #2,-(sp) ; get screen physical base address
trap #14
addq.l #2,sp
move.l d0,phy0 ; save address of screen #0
sub.l #32768,d0
move.l d0,phy1 ; save address of screen #1
sub.l #32768,d0
move.l d0,phy2 ; save address of screen #2
move.l #oldpal,a5 ; save each color number of the old palette
move.w #0,d5
move.w #15,d6
gncolor: move.w #-1,-(sp)
move.w d5,-(sp) ; color number
move.w #7,-(sp)
trap #14
addq.l #6,sp
move.w d0,(a5)+ ; previous color saved
addq.w #1,d5
dbf d6,gncolor
move.w #4,-(sp) ; get and save original resolution
trap #14
addq.l #2,sp
move.w d0,oldres
move.w #0,-(sp) ; switch to low res
move.l #-1,-(sp) ; keep phys addr
move.l #-1,-(sp) ; keep logical addr
move.w #5,-(sp) ; setscreen
trap #14
add.l #12,sp
move.l #newpal,-(sp) ; install new palette
move.w #6,-(sp)
trap #14
addq.l #6,sp
movem.l regsave,d3-d7/a2-a6
rts
;
; This routine restores original resolution, screen, and palette
;
grayexit: move.w oldres,-(sp) ; old resolution
move.l phy0,-(sp) ; old phys addr
move.l phy0,-(sp) ; old logical addr
move.w #5,-(sp) ; setscreen
trap #14
add.l #12,sp
move.l #oldpal,-(sp) ; install old palette
move.w #6,-(sp)
trap #14
addq.l #6,sp
rts
;
; Variable and storage area
;
data
even
newpal: dc.w 0,$111,$222,$333,$444,$555,$666,$777,0,0,0,0,0,0,0,0
oldpal: dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
gtable: dc.b 0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7
dc.b 0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7
dc.b 0,1,0,1,2,1,2,3,2,3,4,3,4,5,4,5,6,5,6,7,6,7
phy0: dc.l 0
phy1: dc.l 0
phy2: dc.l 0
oldres: dc.l 0
wrapit: dc.l 0
corner: dc.l 0
bss
even
regsave: ds.l 16
templine: ds.l 81
;--
;- John Logajan @ Network Systems; 7600 Boone Ave; Brooklyn Park, MN 55428
;- logajan@ns.network.com, 612-424-4888, Fax 612-424-2853